BigQuery に Shift-JIS ファイルのデータをロードするには?
こんにちは、みかみです。
BigQuery にデータをロードする場合、データファイルのエンコーディングは UTF-8(または ISO-8859-1 )がサポートされています。
Shift-JIS(SJIS)ファイルだとロードできないのでしょうか?
やりたいこと
- BigQuery に SJIS ファイルをロードした場合の挙動を確認したい
- BigQuery に SJIS ファイルをロードするにはどうすればいいか知りたい
SJIS ファイルデータをそのままロードしてみる
以下の SJIS の CSV ファイルを準備しました。
col_num,col_alp,col_jp,col_timestamp 12345678,abcdefgh,日本語カタカナ,2021-06-15 00:00:00 99999999,ABCDEFGH,にほんごカタカナ,2021/06/15 23:59:59
file
コマンドでも、エンコーディングが SJIS であることが確認できます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ file sample_sjis.csv sample_sjis.csv: Non-ISO extended-ASCII text
ためしに bq load
コマンドで、SJIS のファイルをそのままロードしてみます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bq load --autodetect \ > --source_format=CSV \ > dataset_1.table_sjis \ > ./sample_sjis.csv Upload complete. Waiting on bqjob_r3b4bebe58e0f35d4_0000017a0e32a660_1 ... (1s) Current status: DONE
エラーにはならず、半角英数などのシングルバイト文字は正常にロードできましたが、マルチバイト文字の日本語は文字化けしてしまいました。。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bq query "select col_jp from dataset_1.table_sjis" Waiting on bqjob_r1b68b5b5432748a_0000017a0e374f00_1 ... (0s) Current status: DONE +----------------+ | col_jp | +----------------+ | ��–{��ƒJƒ^ƒJƒi | | �ɂق?��Å | +----------------+
シェルスクリプトで UTF-8 に変換してからロード
以下の bash スクリプトを準備しました。
#!/bin/bash iconv -f sjis -t utf8 sample_sjis.csv > sample_utf8.csv bq load --autodetect --source_format=CSV dataset_1.table_utf8 ./sample_utf8.csv bq query "select col_jp from dataset_1.table_utf8" > result_table_utf8.txt
iconv
コマンドで UTF-8 に変換した新しいファイルを作成し、作成した UTF-8 のファイルを BigQuery にロードします。
ロード後には結果を確認するため、SJIS のファイルで文字化けしていた日本語カラムのデータを select してファイルに出力してみます。
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ bash ./load_utf8.sh Upload complete. Waiting on bqjob_r45bd90bb2121d699_0000017a0e3e55f2_1 ... (1s) Current status: DONE Waiting on bqjob_r7d034edc5790cb41_0000017a0e3e66a2_1 ... (0s) Current status: DONE
ロード結果の出力ファイルを確認すると
+----------------+ | col_jp | +----------------+ | 日本語カタカナ | | にほんごカタカナ | +----------------+
問題なくロードできているようです。
念のため、BigQuery のテーブルデータも確認してみます。
マルチバイト文字(日本語)も文字化けすることなくテーブルに格納することができました。
pandas DataFrame に読み込んでからロード
ファイルのエンコーディング変換なしで、python プログラムでファイルデータを一度 pandas Dataframeに読み込んでから BigQuery にロードすることもできます。
以下の python コードを実行してみます。
import pandas as pd file_path = './sample_sjis.csv' df = pd.read_csv(file_path, encoding='shift-jis') print(df) dataset_id = 'dataset_1' table_id = 'table_python' df.to_gbq('{}.{}'.format(dataset_id, table_id), if_exists='replace')
mikami_yuki@cloudshell:~/sample/sjis (cm-da-mikami-yuki-258308)$ python3 load_sjis.py col_num col_alp col_jp col_timestamp 0 12345678 abcdefgh 日本語カタカナ 2021-06-15 00:00:00 1 99999999 ABCDEFGH にほんごカタカナ 2021/06/15 23:59:59
ファイルデータが文字化けせずにロードできたか、BigQuery のテーブルデータを確認してみます。
テーブルスキーマを指定しなかったので日時項目も STRING 型で格納されましたが、マルチバイト文字でも文字化けすることなく、正常にロードすることができました。
まとめ(所感)
BigQuery でサポートされていない SJIS ファイルのデータをロードしてもエラーにはなりませんが、日本語などのマルチバイト文字は文字化けしてしまいます。
ロードファイルを初めから UTF-8 で出力できればベストですが、SJIS ファイルのデータでも、シェルスクリプトや python コードで簡単にロードできました。
SJISファイルをロードする場合、ロード前にエンコーディングを UTF-8 に変換してしまうのも良いですが、ロード時にカラムの追加やデータフォーマット変換などの整形処理を行いたい場合は、pandas の DataFrame を使えば、そのまま BigQuery にロードできるので便利です。
なお、本エントリでは pandas.DataFrame
の to_gbq
を使用しましたが、google-cloud-bigquery
ライブラリにも DataFrame を BigQuery にロードするインターフェースがあるので、あわせてご確認ください。